package cn.chuengxu.filter;

import com.alibaba.fastjson.JSON;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

@Component
public class CustomFilter extends ZuulFilter {

    /**======================================================================================
    * @Title: filterType
    * @Description: 设置前缀
    * @Author: Mr.Zhang
    * @Version: 1.0
    * @Date:  2022/7/31 12:10
    * @Parameters: []
    * @Return java.lang.String
    ======================================================================================*/
    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

    /**======================================================================================
    * @Title: filterOrder
    * @Description: 设置执行顺序,数字越小,执行的在越前面
    * @Author: Mr.Zhang
    * @Version: 1.0
    * @Date:  2022/7/31 12:10
    * @Parameters: []
    * @Return int
    ======================================================================================*/
    @Override
    public int filterOrder() {
        return 0;
    }


   /**======================================================================================
   * @Title: shouldFilter
   * @Description: 是否执行下面的run方法
   * @Author: Mr.Zhang
   * @Version: 1.0
   * @Date:  2022/7/31 12:09
   * @Parameters: []
   * @Return boolean
   ======================================================================================*/
    @Override
    public boolean shouldFilter() {
        /**======================================================================================
        * 整体业务逻辑,获取请求地址,判断请求地址是否是登录,注册等公开页面,如果是就放行,如果不是
        * 就走下面的run方法,去判断是否是否包含token信息
        ======================================================================================*/
        // 获取request对象,从request对象中拿去URL
        HttpServletRequest request = RequestContext.getCurrentContext().getRequest();
        // 拿去URL
        String url = request.getRequestURI();

        // 进行判断,如果是就直接放行.
        if (url.endsWith("/login") || url.endsWith("/register ") || url.contains("/static/")){
            return false;
        }

        // 如果不是,就执行核心方法
        return true;
    }


    /**======================================================================================
    * @Title: run
    * @Description: 核心方法,可以用来做登录校验
    * @Author: Mr.Zhang
    * @Version: 1.0
    * @Date:  2022/7/31 12:09
    * @Parameters: []
    * @Return java.lang.Object
    ======================================================================================*/
    @Override
    public Object run() throws ZuulException {
        // 获取request对象
        HttpServletRequest request = RequestContext.getCurrentContext().getRequest();
        // 获取响应给前端的对象
        HttpServletResponse response = RequestContext.getCurrentContext().getResponse();

        // 获取token
        String token = request.getHeader("token");

        // 进行判断信息中是否含有token
        if (!StringUtils.hasLength(token)){
            Map<String, Object> resultMap = new HashMap<>();
            // 添加返回的信息
            resultMap.put("success" , false);
            resultMap.put("message" , "noLogin");

            // 设置响应编码
            response.setContentType("application/json;charset=utf-8");

            // 把map转成json字符串，写到浏览器,因为浏览器接收的是Json格式
            String resultJsonString = JSON.toJSONString(resultMap);

            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);

            // 进行响应
            try {
                response.getWriter().print(resultJsonString);
            } catch (IOException e) {
                e.printStackTrace();
            }

            // 阻止filter继续往后执行
            RequestContext.getCurrentContext().setSendZuulResponse(false);
        }


       // 走到这一步时已经进行放行了,所以不用管这里
        return null;
    }
}
